﻿using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Text;

namespace RobotWebSocketApp
{
    class FanucRobotInf
    {
        private FRRJIf.Core mobjCore;
        private FRRJIf.DataTable mobjDataTable;
        private string strHost;
        private int timeOut;
        public FanucRobotInf()
        {

        }
        public FanucRobotInf(string inputHost)
        {
            strHost = inputHost;
        }
        public void SetHostName(string inputHostName)
        {
            strHost = inputHostName;
        }
        public string GetHostName()
        {
            return strHost;
        }
        public int GetTimeOutValue()
        {
            return timeOut;
        }
        public void SetTimeOutValue(int inputTimeout)
        {
            timeOut = inputTimeout;
        }
        public bool GetTask(string VarType, short VarAddress, ref List<string> Result, ref string ResultMessage)
        {
            mobjCore = new FRRJIf.Core
            {
                TimeOutValue = timeOut
            };
            mobjDataTable = mobjCore.DataTable;

            FRRJIf.DataTask mobjTask;
            switch (VarType)
            {
                case "Task":
                {
                    mobjTask = mobjDataTable.AddTask(FRRJIf.FRIF_DATA_TYPE.TASK, VarAddress);
                    break;
                }
                case "TaskIgnoreMacro":
                {
                    mobjTask = mobjDataTable.AddTask(FRRJIf.FRIF_DATA_TYPE.TASK_IGNORE_MACRO, VarAddress);
                    break;
                }
                case "TaskIgnoreKarel":
                {
                    mobjTask = mobjDataTable.AddTask(FRRJIf.FRIF_DATA_TYPE.TASK_IGNORE_KAREL, VarAddress);
                    break;
                }
                case "TaskIgnoreMacroKarel":
                {
                    mobjTask = mobjDataTable.AddTask(FRRJIf.FRIF_DATA_TYPE.TASK_IGNORE_MACRO_KAREL, VarAddress);
                    break;
                }
                default:
                {
                    mobjTask = mobjDataTable.AddTask(FRRJIf.FRIF_DATA_TYPE.TASK, VarAddress);
                    break;
                }
            }

            bool GetResult = false;

            if (mobjCore.Connect(strHost))
            {
                if (mobjDataTable.Refresh())
                {
                    string strProg = "";
                    short intLine = 0;
                    short intState = 0;
                    string strParentProg = "";
                    if (mobjTask.GetValue(ref strProg, ref intLine, ref intState, ref strParentProg))
                    {
                        Result.Add(MstrTask(mobjTask.Index, strProg, intLine, intState, strParentProg));
                        GetResult = true;
                        ResultMessage = "Robot get value " + VarAddress + " success !";
                    }
                    else
                    {
                        ResultMessage = "Robot get value " + VarAddress + " error !";
                    }
                }
                else
                {
                    ResultMessage = "Robot get value && Robot dataTable Refresh " + VarAddress + " error !";
                }
            }
            else
            {
                ResultMessage = "Robot get value && Robot connect " + VarAddress + " error !";
            }
            mobjCore.Disconnect();
            mobjDataTable = null;
            mobjCore = null;
            return GetResult;
        }
        public bool GetCurPos(string VarType, short VarAddress, short NumberIndex, ref List<string> Result, ref string ResultMessage)
        {
            mobjCore = new FRRJIf.Core
            {
                TimeOutValue = timeOut
            };
            mobjDataTable = mobjCore.DataTable;

            FRRJIf.DataCurPos mobjCurPos;
            switch (VarType)
            {
                case "Pos":
                {
                    mobjCurPos = mobjDataTable.AddCurPos(FRRJIf.FRIF_DATA_TYPE.CURPOS, VarAddress);
                    break;
                }
                case "PosUF":
                {
                    mobjCurPos = mobjDataTable.AddCurPosUF(FRRJIf.FRIF_DATA_TYPE.CURPOS, VarAddress, NumberIndex);
                    break;
                }
                default:
                {
                    mobjCurPos = mobjDataTable.AddCurPos(FRRJIf.FRIF_DATA_TYPE.CURPOS, VarAddress);
                    break;
                }
            }

            bool GetResult = false;

            if (mobjCore.Connect(strHost))
            {
                if (mobjDataTable.Refresh())
                {
                    Array xyzwpr = new float[9];
                    Array config = new short[7];
                    Array joint = new float[9];
                    short intUF = 0;
                    short intUT = 0;
                    short intValidC = 0;
                    short intValidJ = 0;
                    if (mobjCurPos.GetValue(ref xyzwpr, ref config, ref joint, ref intUF, ref intUT, ref intValidC, ref intValidJ))
                    {
                        Result.Add(MstrPos(ref xyzwpr, ref config, ref joint, intValidC, intValidJ, intUF, intUT));
                        GetResult = true;
                        ResultMessage = "Robot get value " + VarAddress + " success !";
                    }
                    else
                    {
                        ResultMessage = "Robot get value " + VarAddress + " error !";
                    }
                }
                else
                {
                    ResultMessage = "Robot get value && Robot dataTable Refresh " + VarAddress + " error !";
                }
            }
            else
            {
                ResultMessage = "Robot get value && Robot connect " + VarAddress + " error !";
            }
            mobjCore.Disconnect();
            mobjDataTable = null;
            mobjCore = null;
            return GetResult;
        }
        public bool GetSysVar(string VarType, string VarAddress, ref List<string> Result, ref string ResultMessage)
        {
            mobjCore = new FRRJIf.Core
            {
                TimeOutValue = timeOut
            };

            mobjDataTable = mobjCore.DataTable;

            FRRJIf.DataSysVar mobjSysVar;
            switch (VarType)
            {
                case "Int":
                {
                    mobjSysVar = mobjDataTable.AddSysVar(FRRJIf.FRIF_DATA_TYPE.SYSVAR_INT, VarAddress);
                    break;
                }
                case "String":
                {
                    mobjSysVar = mobjDataTable.AddSysVar(FRRJIf.FRIF_DATA_TYPE.SYSVAR_STRING, VarAddress);
                    break;
                }
                case "Real":
                {
                    mobjSysVar = mobjDataTable.AddSysVar(FRRJIf.FRIF_DATA_TYPE.SYSVAR_REAL, VarAddress);
                    break;
                }
                default:
                {
                    mobjSysVar = mobjDataTable.AddSysVar(FRRJIf.FRIF_DATA_TYPE.SYSVAR_INT, VarAddress);
                    break;
                }
            }

            object vntValue = null;

            bool GetResult = false;

            if (mobjCore.Connect(strHost))
            {
                if (mobjDataTable.Refresh())
                {
                    if (mobjSysVar.GetValue(ref vntValue))
                    {
                        Result.Add(vntValue.ToString());
                        GetResult = true;
                        ResultMessage = "Robot get value " + VarAddress + " success !";
                    }
                    else
                    {
                        ResultMessage = "Robot get value " + VarAddress + " error !";
                    }
                }
                else
                {
                    ResultMessage = "Robot get value && Robot dataTable Refresh " + VarAddress + " error !";
                }
            }
            else
            {
                ResultMessage = "Robot get value && Robot connect " + VarAddress + " error !";
            }
            mobjCore.Disconnect();
            mobjDataTable = null;
            mobjCore = null;
            return GetResult;
        }
        public bool ReadIO(string IOType, short StartIndex, short NumberIndex, ref List<string> Result, ref string ResultMessage)
        {
            bool blnIO = false;
            Array intIO = new short[NumberIndex];

            mobjCore = new FRRJIf.Core
            {
                TimeOutValue = timeOut
            };

            if (mobjCore.Connect(strHost))
            {
                switch (IOType)
                {
                    case "ReadSDO":
                    {
                        blnIO = mobjCore.ReadSDO(StartIndex, ref intIO, NumberIndex);
                        break;
                    }
                    case "ReadSDI":
                    {
                        blnIO = mobjCore.ReadSDI(StartIndex, ref intIO, NumberIndex);
                        break;
                    }
                    case "ReadRDO":
                    {
                        blnIO = mobjCore.ReadRDO(StartIndex, ref intIO, NumberIndex);
                        break;
                    }
                    case "ReadRDI":
                    {
                        blnIO = mobjCore.ReadRDI(StartIndex, ref intIO, NumberIndex);
                        break;
                    }
                    case "ReadSO":
                    {
                        blnIO = mobjCore.ReadSO(StartIndex, ref intIO, NumberIndex);
                        break;
                    }
                    case "ReadSI":
                    {
                        blnIO = mobjCore.ReadSI(StartIndex, ref intIO, NumberIndex);
                        break;
                    }
                    case "ReadUO":
                    {
                        blnIO = mobjCore.ReadUO(StartIndex, ref intIO, NumberIndex);
                        break;
                    }
                    case "ReadUI":
                    {
                        blnIO = mobjCore.ReadUI(StartIndex, ref intIO, NumberIndex);
                        break;
                    }
                    case "ReadGO":
                    {
                        blnIO = mobjCore.ReadGO(StartIndex, ref intIO, NumberIndex);
                        break;
                    }
                    case "ReadGI":
                    {
                        blnIO = mobjCore.ReadGI(StartIndex, ref intIO, NumberIndex);
                        break;
                    }
                    default:
                    {
                        break;
                    }
                }

                if (blnIO)
                {
                    for (int ii = 0; ii < NumberIndex; ii++)
                    {
                        if ((short)intIO.GetValue(ii) == 0)
                        {
                            Result.Add("0");
                        }
                        else
                        {
                            Result.Add("1");
                        }
                    }
                    ResultMessage = "Robot get " + IOType + " value success !";
                }
                else
                {
                    ResultMessage = "Robot get " + IOType + " value error !";
                }
            }
            else
            {
                blnIO = false;
                ResultMessage = "Robot get SDO && Robot connect error !";
            }
            mobjCore.Disconnect();
            mobjCore = null;
            return blnIO;
        }
        public bool ReadAlarm(short StartIndex, short NumberIndex, ref List<string> Result, ref string ResultMessage)
        {
            mobjCore = new FRRJIf.Core
            {
                TimeOutValue = timeOut
            };
            mobjDataTable = mobjCore.DataTable;

            FRRJIf.DataAlarm mobjAlarm;
            mobjAlarm = mobjDataTable.AddAlarm(FRRJIf.FRIF_DATA_TYPE.ALARM_LIST, StartIndex, NumberIndex);

            bool GetResult = false;

            if (mobjCore.Connect(strHost))
            {
                if (mobjDataTable.Refresh())
                {
                    for (int ii = 1; ii <= StartIndex; ii++)
                    {
                        Result.Add(MstrAlarm(ref mobjAlarm, ii));
                    }
                    GetResult = true;
                    ResultMessage = "Robot get Alarm success !";
                }
                else
                {
                    ResultMessage = "Robot get value && Robot dataTable Refresh Alarm error !";
                }
            }
            else
            {
                ResultMessage = "Robot get value && Robot connect Alarm error !";
            }
            mobjCore.Disconnect();
            mobjDataTable = null;
            mobjCore = null;
            return GetResult;
        }
        public bool GetStringReg(short StartIndex, short NumberIndex, ref List<string> Result, ref string ResultMessage)
        {
            mobjCore = new FRRJIf.Core
            {
                TimeOutValue = timeOut
            };
            mobjDataTable = mobjCore.DataTable;

            FRRJIf.DataString mobjStrReg;
            FRRJIf.DataString mobjStrRegComment;

            mobjStrReg = mobjDataTable.AddString(FRRJIf.FRIF_DATA_TYPE.STRREG, StartIndex, NumberIndex);
            mobjStrRegComment = mobjDataTable.AddString(FRRJIf.FRIF_DATA_TYPE.STRREG_COMMENT, StartIndex, NumberIndex);

            string strValue = "";

            bool GetResult = false;

            if (mobjCore.Connect(strHost))
            {
                if (mobjDataTable.Refresh())
                {
                    string strComment = "";
                    for (int ii = mobjStrReg.StartIndex; ii <= mobjStrReg.EndIndex; ii++)
                    {
                        mobjStrRegComment.GetValue(ii, ref strComment);
                        if (mobjStrReg.GetValue(ii, ref strValue) == true)
                        {
                            Result.Add(String.Format("SR[{0}:{1}] = {2}", ii, strComment, strValue));
                        }
                        else
                        {
                            Result.Add(String.Format("SR[{0}]  : Error!!! ", ii));
                        }
                    }
                    GetResult = true;
                    ResultMessage = "Robot get String Reg success !";
                }
                else
                {
                    ResultMessage = "Robot get value && Robot dataTable Refresh String Reg error !";
                }
            }
            else
            {
                ResultMessage = "Robot get value && Robot connect  String error !";
            }
            mobjCore.Disconnect();
            mobjDataTable = null;
            mobjCore = null;
            return GetResult;
        }
        public bool GetPosReg(string PosRegType, short StartIndex, short NumberIndex, ref List<string> Result, ref string ResultMessage)
        {
            mobjCore = new FRRJIf.Core
            {
                TimeOutValue = timeOut
            };
            mobjDataTable = mobjCore.DataTable;

            FRRJIf.DataPosReg mobjPosReg;
            int.TryParse(PosRegType, out int intA);
            mobjPosReg = mobjDataTable.AddPosReg(FRRJIf.FRIF_DATA_TYPE.POSREG, intA, StartIndex, NumberIndex);

            bool GetResult = false;

            if (mobjCore.Connect(strHost))
            {
                if (mobjDataTable.Refresh())
                {
                    Array xyzwpr = new float[9];
                    Array config = new short[7];
                    Array joint = new float[9];
                    short intUF = 0;
                    short intUT = 0;
                    short intValidC = 0;
                    short intValidJ = 0;
                    for (int ii = mobjPosReg.StartIndex; ii <= mobjPosReg.EndIndex; ii++)
                    {
                        if (mobjPosReg.GetValue(ii, ref xyzwpr, ref config, ref joint, ref intUF, ref intUT, ref intValidC, ref intValidJ))
                        {
                            Result.Add(String.Format("PR[" + ii + "]"+ MstrPos(ref xyzwpr, ref config, ref joint, intValidC, intValidJ, intUF, intUT)));
                        }
                        else
                        {
                            Result.Add(String.Format("PR[" + ii + "] : Error!!! "));
                        }
                    }
                    GetResult = true;
                    ResultMessage = "Robot get Pos Reg success !";
                }
                else
                {
                    ResultMessage = "Robot get value && Robot dataTable Refresh Pos Reg error !";
                }
            }
            else
            {
                ResultMessage = "Robot get value && Robot connect Pos error !";
            }
            mobjCore.Disconnect();
            mobjDataTable = null;
            mobjCore = null;
            return GetResult;
        }
        public bool GetNumberReg(string NumberRegType, short StartIndex, short NumberIndex, ref List<string> Result, ref string ResultMessage)
        {
            mobjCore = new FRRJIf.Core
            {
                TimeOutValue = timeOut
            };
            mobjDataTable = mobjCore.DataTable;

            FRRJIf.DataNumReg mobjNumReg;
            switch (NumberRegType)
            {
                case "Int":
                {
                    mobjNumReg = mobjDataTable.AddNumReg(FRRJIf.FRIF_DATA_TYPE.NUMREG_INT, StartIndex, NumberIndex);
                    break;
                }
                case "Real":
                {
                    mobjNumReg = mobjDataTable.AddNumReg(FRRJIf.FRIF_DATA_TYPE.NUMREG_REAL, StartIndex, NumberIndex);
                    break;
                }
                default:
                {
                    mobjNumReg = mobjDataTable.AddNumReg(FRRJIf.FRIF_DATA_TYPE.NUMREG_INT, StartIndex, NumberIndex);
                    break;
                }
            }

            bool GetResult = false;
            object vntValue = null;

            if (mobjCore.Connect(strHost))
            {
                if (mobjDataTable.Refresh())
                {
                    for (int ii = mobjNumReg.StartIndex; ii <= mobjNumReg.EndIndex; ii++)
                    {
                        if (mobjNumReg.GetValue(ii, ref vntValue) == true)
                        {
                            Result.Add(String.Format("R[" + ii + "] = " + vntValue));
                        }
                        else
                        {
                            Result.Add(String.Format("R[" + ii + "] = " + "Error!!!"));
                        }
                    }
                    GetResult = true;
                    ResultMessage = "Robot get Number Reg success !";
                }
                else
                {
                    ResultMessage = "Robot get value && Robot dataTable Refresh Number Reg error !";
                }
            }
            else
            {
                ResultMessage = "Robot get value && Robot connect Number error !";
            }
            mobjCore.Disconnect();
            mobjDataTable = null;
            mobjCore = null;
            return GetResult;
        }
        private string MstrTask(int Index, string strProg, short intLine, short intState, string strParentProg)
        {
            string tmp = null;

            tmp = "TASK" + Index + " : ";
            tmp = tmp + " Prog=" + strProg;
            tmp = tmp + " Line=" + intLine;
            tmp = tmp + " State=" + intState;
            tmp = tmp + " ParentProg=" +strParentProg;

            return tmp;
        }
        private string MstrPos(ref Array xyzwpr, ref Array config, ref Array joint, short intValidC, short intValidJ, int UF, int UT)
        {
            string tmp = "";
            int ii = 0;

            tmp = tmp + "UF = " + UF + ";";
            tmp = tmp + "UT = " + UT + ";";
            if (intValidC != 0)
            {
                tmp = tmp + "XYZWPR = ";
                //5
                for (ii = 0; ii <= 8; ii++)
                {
                    tmp = tmp + xyzwpr.GetValue(ii) + " ";
                }

                tmp = tmp + ";" + "CONFIG = ";
                if ((short)config.GetValue(0) != 0)
                {
                    tmp = tmp + "F ";
                }
                else
                {
                    tmp = tmp + "N ";
                }
                if ((short)config.GetValue(1) != 0)
                {
                    tmp = tmp + "L ";
                }
                else
                {
                    tmp = tmp + "R ";
                }
                if ((short)config.GetValue(2) != 0)
                {
                    tmp = tmp + "U ";
                }
                else
                {
                    tmp = tmp + "D ";
                }
                if ((short)config.GetValue(3) != 0)
                {
                    tmp = tmp + "T ";
                }
                else
                {
                    tmp = tmp + "B ";
                }
                tmp = tmp + String.Format("{0} {1} {2};", config.GetValue(4), config.GetValue(5), config.GetValue(6));
            }

            if (intValidJ != 0)
            {
                tmp = tmp + "JOINT = ";
                //5
                for (ii = 0; ii <= 8; ii++)
                {
                    tmp = tmp + joint.GetValue(ii) + " ";
                }
                tmp = tmp + ";";
            }

            return tmp;

        }
        private string MstrAlarm(ref FRRJIf.DataAlarm objAlarm, int Count)
        {
            short intID = 0;
            short intNumber = 0;
            short intCID = 0;
            short intCNumber = 0;
            short intSeverity = 0;
            short intY = 0;
            short intM = 0;
            short intD = 0;
            short intH = 0;
            short intMn = 0;
            short intS = 0;
            string strM1 = "";
            string strM2 = "";
            string strM3 = "";
            bool blnRes = objAlarm.GetValue(Count, ref intID, ref intNumber, ref intCID, ref intCNumber, 
                                                                           ref intSeverity, ref intY, ref intM, ref intD, ref intH,
                                                                           ref intMn, ref intS, ref strM1, ref strM2, ref strM3);
            string tmp;
            //tmp = "-- Alarm " + Count + " --;";
            if (blnRes == false)
            {
                tmp = "Error";
                return tmp;
            }
            /*
            tmp = tmp + intID + ", " + intNumber + ", " + intCID + ", " + intCNumber + ", " + intSeverity + ";";
            tmp = tmp + intY + "/" + intM + "/" + intD + ", " + intH + ":" + intMn + ":" + intS + ";";
            if (!string.IsNullOrEmpty(strM1))
                tmp = tmp + strM1 + ";";
            if (!string.IsNullOrEmpty(strM2))
                tmp = tmp + strM2 + ";";
            if (!string.IsNullOrEmpty(strM3))
                tmp = tmp + strM3 + ";";
            */
            SysAlarm sysAlarm = new SysAlarm
            {
                MID = intID,
                MNumber = intNumber,
                CID = intCID,
                CNumber = intCNumber,
                Severity = intSeverity,
                Time = intY + "-" + intM + "-" + intD + " " + intH + ":" + intMn + ":" + intS,
                Content = strM1 + strM2,
                Type = strM3
            };
            //UTF8Encoding utf8 = new UTF8Encoding();
            //Byte[] encodeBytes = utf8.GetBytes(JsonConvert.SerializeObject(sysAlarm));
            //tmp = utf8.GetString(encodeBytes);
            //tmp = JsonConvert.SerializeObject(JsonConvert.DeserializeObject(sysAlarm), Formatting.Indented);
            //Console.WriteLine(tmp);
            tmp = "{ \"MID\":"+ intID.ToString() + ",\"MNumber\":"+ intNumber.ToString()+ 
                        ",\"CID\":" + intCID.ToString() + ",\"CNumber\":" + intCNumber.ToString()+ 
                        ",\"Severity\":" + intSeverity.ToString() + 
                        ",\"Time\":\""+ sysAlarm.Time+ 
                        "\",\"Content\":\"" + sysAlarm.Content +
                        "\",\"Type\":\"" + sysAlarm.Type + "\"}";

            Console.WriteLine(tmp);
            Console.WriteLine(JsonConvert.SerializeObject(sysAlarm));
            string ret = JsonConvert.SerializeObject(sysAlarm);
            Console.WriteLine(ret);
            return tmp;
        }
    }
}
